<template>


  <el-dialog
    title="截图"
    :visible="cropperVisible"
    width="90%"
    :append-to-body="appendToBody"
    :destroy-on-close="isTrue"
    :before-close="cropperVisibleClone">


    <el-row>
      <el-col :span="16">

        <div class="cut">
          <!--    图片插件-->
          <vue-cropper ref="cropper" :img="option.img" :output-size="option.size" :output-type="option.outputType"
                       :info="true" :full="option.full" :fixed="fixed" :fixed-number="fixedNumber"
                       :can-move="option.canMove" :can-move-box="option.canMoveBox" :fixed-box="option.fixedBox"
                       :original="option.original"
                       :auto-crop="option.autoCrop" :auto-crop-width="option.autoCropWidth"
                       :auto-crop-height="option.autoCropHeight" :center-box="option.centerBox"
                       @real-time="realTime" :high="option.high"
                       @img-load="imgLoad" :max-img-size="option.max" @crop-moving="cropMoving"
                       mode="cover">
          </vue-cropper>
        </div>

      </el-col>

      <el-col :span="8">
        <!--    预览图片展示部分-->
        <div :style="{'width': previews.w + 'px', 'height': previews.h + 'px',  'overflow': 'hidden', 'margin-top': '20px'}">
          <div :style="previews.div">
            <img :src="previews.url" :style="previews.img">
          </div>
        </div>
      </el-col>


    </el-row>


    <el-row>
      <el-col :span="24">

<!--        <button @click="refreshCrop" class="btn">重置</button>-->

<!--        <button @click="changeScale(1)" class="btn">放大</button>-->



<!--        <button @click="changeScale(-1)" class="btn">缩小</button>-->
<!--        <button @click="rotateLeft" class="btn">左转</button>-->
<!--        <button @click="rotateRight" class="btn">右转</button>-->

<!--        <label class="btn" for="uploads">上传图片</label>-->

<!--        <label class="btn" for="uploads" >上传图片</label>-->
        <el-button type="primary" icon="el-icon-upload" size="small" @click="goFile">上传图片</el-button>
        <input type="file" ref="files" id="uploads" style="position:absolute; clip:rect(0 0 0 0);" accept="image/png, image/jpeg, image/gif, image/jpg" @change="uploadImg($event, 1)">
        &nbsp;
        <el-button type="success" icon="el-icon-picture" size="small" @click="getImage">裁剪</el-button>
        <el-button type="primary" icon="el-icon-document-remove" size="small" @click="refreshCrop">重置</el-button>
        <el-button type="primary" icon="el-icon-plus" size="small" @click="changeScale(1)">放大</el-button>
        <el-button type="primary" icon="el-icon-minus" size="small" @click="changeScale(-1)">缩小</el-button>
        <el-button type="primary" icon="el-icon-s-ticket" size="small" @click="rotateLeft">左转</el-button>
        <el-button type="primary" icon="el-icon-s-open" size="small" @click="rotateRight">右转</el-button>

      </el-col>

<!--      <el-col :span="6">-->
<!--        <button @click="finish('base64')" class="btn">展示图片(base64)</button>-->
<!--        <button @click="finish('blob')" class="btn">展示图片(blob)</button>-->
<!--      </el-col>-->
<!--      <el-col :span="6">-->
<!--        <a @click="down('base64')" class="btn">下载图片(base64)</a>-->
<!--        <a @click="down('blob')" class="btn">下载图片(blob)</a>-->
<!--      </el-col>-->
    </el-row>




    <span slot="footer" class="dialog-footer">
      <el-button @click="cropperVisibleClone">关 闭</el-button>
<!--      <el-button type="primary" @click="cropperVisible = false">确 定</el-button>-->
    </span>
  </el-dialog>




</template>

<script>

  // 参考：https://codepen.io/xyxiao001/pen/wxwKGz
  // 文档：https://github.com/xyxiao001/vue-cropper
  // 使用方法，通过this.$refs.cropper.cropperVisible=true 来设置图片，父组件实现setImagesFile方法来接收返回参数

  import {VueCropper} from 'vue-cropper'

  export default {
    name: "ImagePortrait",
    components: {
      VueCropper
    },
    props: {

    },
    data() {
      return {
        // 弹框是否打开
        cropperVisible: false,
        // 无特殊含义，就是用来标识布尔值的
        isTrue: true,
        isFalse: false,
        // Dialog 自身是否插入至 body 元素上。嵌套的 Dialog 必须指定该属性并赋值为 true
        appendToBody: true,
        // 图片预览，预览的图片
        previews: {},
        // vue-cropper 参数
        option: {
          // 要进行截图的图片
          img: '',
          // 裁剪生成图片的质量, 范围 0.1 ~ 1，默认 1
          size: 1,
          // 是否输出原图比例的截图,默认 false
          full: true,
          // 裁剪生成图片的格式,默认jpg (jpg 需要传入jpeg)
          outputType: 'png',
          // 上传图片是否可以移动,默认 true
          canMove: false,
          // 固定截图框大小,默认 不允许改变
          fixedBox: false,
          // 上传图片按照原始比例渲染,默认 false
          original: true,
          // 截图框能否拖动,默认 true
          canMoveBox: true,
          // 是否默认生成截图框,默认 false
          autoCrop: true,
          // 默认生成截图框宽度,默认容器的 80%。只有自动截图开启 宽度高度才生效
          // autoCropWidth: 260,
          // 默认生成截图框高度,默认容器的 80%。只有自动截图开启 宽度高度才生效
          // autoCropHeight: 250,
          // 截图框是否被限制在图片里面,默认 false
          centerBox: false,
          // 是否按照设备的dpr 输出等比例图片,默认 true
          high: true,
          // 限制图片最大宽度和高度,默认 2000
          max: 2000,
        },
        // 截图框的宽高比例, 默认 [1, 1]
        // fixedNumber: [16, 9],
        fixedNumber: [1, 1],
        // 是否开启截图框宽高固定比例,默认 false
        fixed: false,
      }
    },
    methods: {
      /**
       * 设置图片到父组件，父组件必须定义该方法
       * @param data 获取的文件，blob类型
       */
      setImagesFile(data){
        // console.log(data)
        this.$emit('setImagesFile', data)
        this.cropperVisibleClone()
      },
      /**
       * 获取截图文件
       */
      getImage() {
        this.$refs.cropper.getCropBlob((data) => {
          this.setImagesFile(data)
        })
      },
      /**
       * 点击上传文件触发input文件
       */
      goFile(){
        this.$refs.files.click();
      },
      /**
       * 关闭当前弹框
       */
      cropperVisibleClone(){
        this.refreshCrop()
        this.cropperVisible = false;
      },
      /**
       * 图片实时预览
       * @param data
       */
      realTime(data) {
        this.previews = data
        // console.log(data)
      },
      /**
       * 图片加载的回调, 返回结果 success, error
       * @param msg 回结果 success, error
       */
      imgLoad(msg) {
        if (msg === 'error'){
        }
        // console.log(msg)
      },
      /**
       * 截图框移动回调函数，
       * 返回的参数内容，
       * {
           moving: true, // moving 是否在移动
           axis: {
             x1: 1, // 左上角
             x2: 1，// 右上角
             y1: 1，// 左下角
             y2: 1 // 右下角
           }
         }
       * @param data
       */
      cropMoving(data) {
        // console.log(data, '截图框当前坐标')
      },
      /**
       * 重置截图图片
       */
      refreshCrop() {
        // clear
        // this.$refs.cropper.refresh()
        this.option.img = ''
      },
      /**
       * 改变图片大小，修改图片大小 正数为变大 负数变小
       * @param num
       */
      changeScale(num) {
        num = num || 1
        this.$refs.cropper.changeScale(num)
      },
      /**
       * 向左边旋转90度
       */
      rotateLeft() {
        this.$refs.cropper.rotateLeft()
      },
      /**
       * 向右边旋转90度
       */
      rotateRight() {
        this.$refs.cropper.rotateRight()
      },
      /**
       * 输出生成图片
       * @param type 生成图片类型，base64 或者  blob
       */
      finish(type) {
        // 输出
        // var test = window.open('about:blank')
        // test.document.body.innerHTML = '图片生成中..'
        if (type === 'blob') {
          this.$refs.cropper.getCropBlob((data) => {
            // console.log(data);
            // var img = window.URL.createObjectURL(data)
            // this.modelSrc = img
          })
        } else {
          this.$refs.cropper.getCropData((data) => {
            // this.model = true
            // this.modelSrc = data
          })
        }
      },
      /**
       * 下载图片
       * @param type 生成图片类型，base64 或者  blob
       */
      down(type) {
        let aLink = document.createElement('a')
        aLink.download = 'demo'
        // 输出
        if (type === 'blob') {
          this.$refs.cropper.getCropBlob((data) => {
            this.downImg = window.URL.createObjectURL(data)
            aLink.href = window.URL.createObjectURL(data)
            aLink.click()
          })
        } else {
          this.$refs.cropper.getCropData((data) => {
            this.downImg = data
            aLink.href = data
            aLink.click()
          })
        }
      },
      /**
       * 上传图片
       * @param e 事件
       * @param num
       * @return {boolean}
       */
      uploadImg(e, num) {
        //上传图片
        // this.option.img
        var file = e.target.files[0]
        if (!/\.(gif|jpg|jpeg|png|bmp|GIF|JPG|PNG)$/.test(e.target.value)) {
          alert('图片类型必须是.gif,jpeg,jpg,png,bmp中的一种')
          return false
        }
        var reader = new FileReader()
        reader.onload = (e) => {
          let data
          if (typeof e.target.result === 'object') {
            // 把Array Buffer转化为blob 如果是base64不需要
            data = window.URL.createObjectURL(new Blob([e.target.result]))
          } else {
            data = e.target.result
          }
          if (num === 1) {
            this.option.img = data
          } else if (num === 2) {
            // this.example2.img = data
          }
        }
        // 转化为base64
        // reader.readAsDataURL(file)
        // 转化为blob
        reader.readAsArrayBuffer(file)
      },
    }
  }
</script>

<style scoped>

  .cut {
    width: 500px;
    height: 500px;
    margin: 20px auto;
  }

  code.language-html {
    padding: 10px 20px;
    margin: 10px 0px;
    display: block;
    background-color: #333;
    color: #fff;
    overflow-x: auto;
    font-family: Consolas, Monaco, Droid, Sans, Mono, Source, Code, Pro, Menlo, Lucida, Sans, Type, Writer, Ubuntu, Mono;
    border-radius: 5px;
    white-space: pre;
  }

  .show-info {
    margin-bottom: 50px;
  }

  .show-info h2 {
    line-height: 50px;
  }

  /*.title, .title:hover, .title-focus, .title:visited {
    color: black;
  }*/

  .title {
    display: block;
    text-decoration: none;
    text-align: center;
    line-height: 1.5;
    margin: 20px 0px;
    background-image: -webkit-linear-gradient(left,#3498db,#f47920 10%,#d71345 20%,#f7acbc 30%,#ffd400 40%,#3498db 50%,#f47920 60%,#d71345 70%,#f7acbc 80%,#ffd400 90%,#3498db);
    color: transparent;
    -webkit-background-clip: text;
    background-size: 200% 100%;
    animation: slide 5s infinite linear;
    font-size: 40px;
  }

  .test {
    height: 500px;
  }

  .model {
    position: fixed;
    z-index: 10;
    width: 100vw;
    height: 100vh;
    overflow: auto;
    top: 0;
    left: 0;
    background: rgba(0, 0, 0, 0.8);
  }

  .model-show {
    display: flex;
    justify-content: center;
    align-items: center;
    width: 100vw;
    height: 100vh;
  }

  .model img {
    display: block;
    margin: auto;
    max-width: 80%;
    user-select: none;
    background-position: 0px 0px, 10px 10px;
    background-size: 20px 20px;
    background-image: linear-gradient(45deg, #eee 25%, transparent 25%, transparent 75%, #eee 75%, #eee 100%),linear-gradient(45deg, #eee 25%, white 25%, white 75%, #eee 75%, #eee 100%);
  }

  .c-item {
    display: block;
    user-select: none;
  }


</style>
